# Module 'commands'
#
# Outils variés permettant d'exécuter des commandes et d'observer la sortie
# et l'état de ces commandes

import rand
import posix
import path


# Obtient l'état d'un objet grâce à la commande 'ls -l'; le place dans une
# chaîne
#
def getstatus(file):
	return getoutput('ls -ld' + mkarg(file))


# Obtient la sortie générée par une commande shell et la place dans une chaîne.
# L'état de sortie de la commande est ignoré; on enlève le saut de ligne
# présent en toute fin de la chaîne (s'il y en a un).
# Cette fonction suppose que la commande spécifiée fonctionne si on lui ajoute
# à la fin ' >fichier-temporaire 2>&1'.
# XXX Cette fonction devrait plutôt utiliser posix.popen(), si cette dernière
#     existait
#
def getoutput(cmd):
	return getstatusoutput(cmd)[1]


# Idem, mais conserve l'état de sortie de la commande.
# Renvoie une paire (état, sortie)
#
def getstatusoutput(cmd):
	tmp = '/usr/tmp/wdiff' + `rand.rand()`
	sts = -1
	try:
		sts = posix.system(cmd + ' >' + tmp + ' 2>&1')
		text = readfile(tmp)
	finally:
		altsts = posix.system('rm -f ' + tmp)
	if text[-1:] = '\n': text = text[:-1]
	return sts, text


# Renvoie une chaîne contenant le contenu d'un fichier.
#
def readfile(fn):
	fp = open(fn, 'r')
	a = ''
	n = 8096
	while 1:
		b = fp.read(n)
		if not b: break
		a = a + b
	return a


# Construit un argument pour commande shell à partir du chemin d'accès d'un
# répertoire et du nom d'un fichier (on fait précéder la chaîne spécifiée d'un
# espace et on ajoute des guillemets).
# 
#
def mk2arg(head, x):
	return mkarg(path.cat(head, x))


# Construit un argument pour commande shell à partir d'une chaîne.
# Deux possibilités : on inclut l'argument entre guillemets simples si la
# chaîne spécifiée n'en contient aucun; sinon, on l'inclut entre guillemets
# doubles et on précède les caractères devant être échappés par un antislash.
#
def mkarg(x):
	if '\'' not in x:
		return ' \'' + x + '\''
	s = ' "'
	for c in x:
		if c in '\\$"':
			s = s + '\\'
		s = s + c
	s = s + '"'
	return s
